{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f09fd305",
   "metadata": {},
   "source": [
    "# Code writing\n",
    "\n",
    "Example of how to use LCEL to write Python code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0653c7c7",
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install --upgrade --quiet  gigachain-core gigachain-experimental langchain-openai"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "bd7c259a",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.chat_models import GigaChat\n",
    "from langchain_core.output_parsers import StrOutputParser\n",
    "from langchain_core.prompts import (\n",
    "    ChatPromptTemplate,\n",
    ")\n",
    "from langchain_experimental.utilities import PythonREPL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "73795d2d",
   "metadata": {},
   "outputs": [],
   "source": [
    "template = \"\"\"Write some python code to solve the user's problem. \n",
    "\n",
    "Return only python code in Markdown format, e.g.:\n",
    "\n",
    "```python\n",
    "....\n",
    "```\"\"\"\n",
    "prompt = ChatPromptTemplate.from_messages([(\"system\", template), (\"human\", \"{input}\")])\n",
    "\n",
    "\n",
    "model = GigaChat(credentials=\"<token>\", model=\"<не ниже -large>\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "42859e8a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def _sanitize_output(text: str):\n",
    "    _, after = text.split(\"<code>{python}\")\n",
    "    return after.split(\"</code>\")[0]\n",
    "\n",
    "\n",
    "def _print_output(text: str):\n",
    "    print(\"Running code: \\n\" + text + \"\\n\")\n",
    "    return text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "5ded1a86",
   "metadata": {},
   "outputs": [],
   "source": [
    "chain = (\n",
    "    prompt\n",
    "    | model\n",
    "    | StrOutputParser()\n",
    "    | _sanitize_output\n",
    "    | _print_output\n",
    "    | PythonREPL().run\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "208c2b75",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running code: \n",
      "print(5*4*3*2*1)\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'120'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke({\"input\": \"чему равен 5 факториал?\"}).strip()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "6be503d5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running code: \n",
      "# Сохраним максимальное значение\n",
      "max_num = 0\n",
      "# Итерируемся по трехзначным числам\n",
      "for i in range(100, 999):\n",
      "    # Если число делится на 17, то сохраняем его\n",
      "    if i % 17 == 0:\n",
      "        max_num = i\n",
      "# Выводим результат\n",
      "print(max_num)\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'986'"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\n",
    "    {\"input\": \"Выведи самое большое трехзначное число, которое делится на 17\"}\n",
    ").strip()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "df934c57",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running code: \n",
      "# Присваиваем переменной базовый депозит\n",
      "deposit = 1000\n",
      "# Присваиваем переменной процентную ставку\n",
      "percentage = 0.1\n",
      "# Присваиваем переменной сумму ежегодного снятия\n",
      "withdrawal = 110\n",
      "# Инициализируем переменную для хранения суммы денег на счету\n",
      "money = deposit\n",
      "# Инициализируем переменную для хранения количества лет\n",
      "years = 0\n",
      "# Запускаем цикл по количеству лет\n",
      "while years <= 10:\n",
      "    # Увеличиваем сумму денег на счету на проценты\n",
      "    money += money * percentage\n",
      "    # Вычитаем из суммы денег на счету ежегодное снятие\n",
      "    money -= withdrawal\n",
      "    # Увеличиваем количество лет на единицу\n",
      "    years += 1\n",
      "# Выводим результат\n",
      "print(money)\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'814.6883293890003'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\n",
    "    {\n",
    "        \"input\": \"Я положил на счет 1000 рублей под 10% годовых. Каждый год я снимаю со счета 110 рублей. Сколько денег у меня будет через 10 лет с учетом капитализации?\"\n",
    "    }\n",
    ").strip()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
